#include "socket_handle.h"

void node_client_send_handler(int a, char *send_buffer, ca_self *self, uint8_t *sk_flag) // TO BE COMPELETED
{
    char prehead[] = "00";
    switch (a)
    {
    case 6:
        prehead[0] = '6';
        memmove(send_buffer, prehead, 1);
        memmove(send_buffer + 1, self->datapackage, 96);
        memmove(send_buffer + 1 + 96, self->selfid, 8);
        memmove(send_buffer + 1 + 96 + 8, sk_flag, 1);
        break;
    case -1:
        memmove(send_buffer, 'k', 1);
        break;
    default:
        break;
    }
}

void node_client_receive_handler(char *node_client_rec_buffer, TEEC_Context ctx, TEEC_Session sess, TEEC_Context ctx2, TEEC_Session sess2, ca_self *self, ca_oppo *oppo)
{
    TEEC_Result res;
    switch (node_client_rec_buffer[0])
    {
    case '1':
    {
        uint8_t case1_oppo_sig_pk[SIG_PK_LEN];
        uint8_t case1_oppo_id[8];
        memmove(case1_oppo_sig_pk, node_client_rec_buffer + 1, SIG_PK_LEN);
        memmove(case1_oppo_id, node_client_rec_buffer + 1 + SIG_PK_LEN, 8);
        res = save_opposigpk_invoke(ctx, sess, case1_oppo_id, case1_oppo_sig_pk);
        res = kem_keypair_invoke(ctx, sess, Ca_Sig_Msg);
        break;
    }
    case '2':
    {
        uint8_t case2_sig_ct[CT_LEN + SIGNATURE_LEN];
        uint8_t case2_oppo_id[8];
        uint8_t case2_auth_res[2]={0};
        size_t case2_sig_res_len;
        uint8_t case2_f_key[16];
        memmove(case2_sig_ct, node_client_rec_buffer + 1, CT_LEN + SIGNATURE_LEN);
        memmove(case2_oppo_id, node_client_rec_buffer + 1 + CT_LEN + SIGNATURE_LEN, 8);
        memmove(oppo->oppoid, node_client_rec_buffer + 1 + CT_LEN + SIGNATURE_LEN, 8);
        res = authen_decape_invoke(ctx, sess, case2_oppo_id, case2_sig_ct, case2_auth_res);

        uint8_t case2_sig_res[2 + SIGNATURE_LEN];

        printf("\n4. Start \033[1;34m\"Signature Key Verification Data\"\033[0m\n");
        struct timeval start, end;
        gettimeofday(&start, NULL);

        res = ta_sign_invoke(ctx, sess, case2_oppo_id, case2_auth_res, case2_sig_res, &case2_sig_res_len);
        
        gettimeofday(&end, NULL);
        long timeuse = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
        printf("4. Signature Key Verification Data Time=%.3fms\n", timeuse / 1000.0);
        printf("4. \033[1;34m\"Signature Key Verification Data\"\033[0m is \033[1;32mAccomplished\033[0m!\n");
	
        memmove(Auth_Res, case2_sig_res, 2 + SIGNATURE_LEN);
        // printf("2.client_sign_succes\n");
        break;
    }
    case '6':
    {
        uint8_t case6_auth_sig[2 + SIGNATURE_LEN];
        uint8_t case6_auth_res[2]={0};
        size_t case6_auth_res_len;
        uint8_t case6_oppo_id[8];
        memmove(case6_oppo_id, node_client_rec_buffer + 1, 8);
        memmove(case6_auth_sig, node_client_rec_buffer + 1 + 8, 2 + SIGNATURE_LEN);

        res = ta_sign_verify_context_invoke(ctx, sess, case6_oppo_id, case6_auth_sig, case6_auth_res, &case6_auth_res_len);
        
        if (case6_auth_res[0] == '1')
        {
            printf("\nContent Authentication \033[1;32mSucceeded\033[0m!\n");
            res = Context_Update(ctx2, sess2, 1);
            // printf("Update 1\n");
        }
        else
        {
            printf("\nContent Authentication \033[1;31mFailed\033[0m!\n");
            res = Context_Update(ctx2, sess2, 0);
            // printf("Update 0\n");
        }
        break;
    }
    case 'n':
        printf("\nOpponode_is_identifing, please wait!\n");
        wait(10000);
        break;
    case 'k':
        printf("\nThis ID is unregistered!\n");
        break;
    default:
        break;
    }
}

void node_server_receive_handler(TEEC_Context ctx, TEEC_Session sess, TEEC_Context ctx2, TEEC_Session sess2,
                                 char *node_server_rec_buffer, char *send_buffer, int send_bufferLen, ca_oppo *oparams,
                                 ca_self *sparams)
{
    // void *socket;
    TEEC_Result res;
    // char *node_server_rec_buffer;
    char prehead[] = "00";
    switch (node_server_rec_buffer[0])
    {
    case '1':
    {
        prehead[0] = '1';
        uint8_t case1_oppo_sig_pk[SIG_PK_LEN];
        uint8_t case1_oppo_id[8];
        memmove(case1_oppo_sig_pk, node_server_rec_buffer + 1, SIG_PK_LEN);
        memmove(case1_oppo_id, node_server_rec_buffer + 1 + SIG_PK_LEN, 8);
        
        res = save_opposigpk_invoke(ctx, sess, case1_oppo_id, case1_oppo_sig_pk);
        
        memmove(send_buffer, prehead, 1);
        memmove(send_buffer + 1, Ca_Self_Sig_Pk, SIG_PK_LEN);
        memmove(send_buffer + 1 + SIG_PK_LEN, Ca_Self_ID, 8);
        break;
    }
    case '2':
    {
        printf("\n**************************************************************\n");
	    printf("                  Identity Authentication\n");
        prehead[0] = '2';
        uint8_t case2_sig_msg[KEM_PK_LEN + SIGNATURE_LEN];
        uint8_t case2_sig_ct[CT_LEN + SIGNATURE_LEN];
        uint8_t case2_oppo_id[8];
        memmove(case2_sig_msg, node_server_rec_buffer + 1, KEM_PK_LEN + SIGNATURE_LEN);
        memmove(case2_oppo_id, node_server_rec_buffer + 1 + KEM_PK_LEN + SIGNATURE_LEN, 8);
        res = authen_encape_invoke(ctx, sess, case2_oppo_id, case2_sig_msg, case2_sig_ct);
        res = Sk_Secure_Read(ctx2, sess2, case2_oppo_id);
        memmove(send_buffer, prehead, 1);
        memmove(send_buffer + 1, case2_sig_ct, CT_LEN + SIGNATURE_LEN);
        memmove(send_buffer + 1 + CT_LEN + SIGNATURE_LEN, Ca_Self_ID, 8);
        break;
    }
    case '3':
    {
        // prehead[0] = '4';
        uint8_t case3_auth_sig[2 + SIGNATURE_LEN];
        uint8_t case3_auth_res[2]={0};
        size_t case3_auth_res_len;
        uint8_t case3_oppo_id[8];
        memmove(case3_oppo_id, node_server_rec_buffer + 1, 8);


        memmove(case3_auth_sig, node_server_rec_buffer + 1 + 8, 2 + SIGNATURE_LEN);

        res = ta_sign_verify_invoke(ctx, sess, case3_oppo_id, case3_auth_sig, case3_auth_res, &case3_auth_res_len);

        if (case3_auth_res[0] == '1')
        {
            printf("5. \033[1;32mSucceed\033[0m Verify Key Verification Data \n");
        }
        else
        {
            printf("5. \033[1;31mFailed\033[0m Verify Key Verification Data \n");
        }
        printf("5. \033[1;34m\"Verify Key Verification Data\"\033[0m is \033[1;32mAccomplished\033[0m!\n");
        printf("\nIdentification Authentication is \033[1;32mAccomplished\033[0m\n");
	    printf("**************************************************************\n");
        
        break;
    
    }
    case '6':
    {
        prehead[0] = '6';
        uint8_t con_oppo_id[8];
        uint8_t sk_update_flag = 0;
        uint8_t package[96];
        char rec_data[72];
        uint8_t case6_auth_res[2] = "00";
        memmove(package, node_server_rec_buffer + 1, 96);
        memmove(con_oppo_id, node_server_rec_buffer + 1 + 96, 8);
        memmove(&sk_update_flag, node_server_rec_buffer + 1 + 96 + 8, 1);
        
        res = Context_DeHmac(ctx2, sess2, con_oppo_id, package, rec_data, &sk_update_flag);
        //此处可以判断成功或失败，是否要回传data
        //需要给client回传内容认证结果 0x01为成功 0x00为失败
        // memmove(send_buffer, prehead, 1);
        // memmove(send_buffer + 1, rec_data, 1);
        // printf("rec_data[0]:%d\n", rec_data[0]);
        // printf("6 res:%x\n", res);

        if (rec_data[0] == 0x01)
        {
            //将data存储或回传;
            char buff[128] = {0};
            int ten = rec_data[1] - '0';
            int one = rec_data[2] - '0';
            int len = ten * 10 + one;
            //printf("\n%d\n", len);
            for (int i = 3; i < 3 + len; ++i)
            {
                buff[i - 3] = rec_data[i];
            }
            buff[len] = '\0';
            printf("\nDecrypted Data:\n", buff);
            printf("\033[1;34m%s\033[0m\n", buff);
            case6_auth_res[0] = '1';
        }
        else
        {
            printf("\nContent Authentication \033[1;31mFailed\033[0m\n");
        }

        size_t case6_sig_res_len;
        uint8_t case6_sig_res[2 + SIGNATURE_LEN];

        printf("\nStart \033[1;34m\"Signature Content Authentication Result\"\033[0m\n");
        struct timeval start, end;
        gettimeofday(&start, NULL);

        res = ta_sign_invoke(ctx, sess, con_oppo_id, case6_auth_res, case6_sig_res, &case6_sig_res_len);
        
        gettimeofday(&end, NULL);
        long timeuse = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
        printf("Signature Content Authentication Result Time=%.3fms\n", timeuse / 1000.0);
        printf("\033[1;34m\"Signature Content Authentication Result\"\033[0m is \033[1;32mAccomplished\033[0m!\n");
        printf("-------------------------------------------------------\n");

        // memmove(Auth_Res, case2_sig_res, 2 + SIGNATURE_LEN);
        memmove(send_buffer, prehead, 1);
        memmove(send_buffer + 1, Ca_Self_ID, 8);
        memmove(send_buffer + 1 + 8, case6_sig_res, 2 + SIGNATURE_LEN);
        break;
    }
    default:
        break;
    }
}

void pqc_node_client_send_handler(int a, char *send_buffer)
{
    char prehead[] = "00";
    switch (a)
    {
    case 1:
        prehead[0] = '1';
        memmove(send_buffer, prehead, 1);
        memmove(send_buffer + 1, Ca_Self_Sig_Pk, SIG_PK_LEN);
        memmove(send_buffer + 1 + SIG_PK_LEN, Ca_Self_ID, 8);
        break;
    case 2:
        prehead[0] = '2';
        memmove(send_buffer, prehead, 1);
        memmove(send_buffer + 1, Ca_Sig_Msg, KEM_PK_LEN + SIGNATURE_LEN);
        memmove(send_buffer + 1 + KEM_PK_LEN + SIGNATURE_LEN, Ca_Self_ID, 8);
        break;
    case 3:
    {
        prehead[0] = '3';
        memmove(send_buffer, prehead, 1);
        memmove(send_buffer + 1, Ca_Self_ID, 8);
        memmove(send_buffer + 1 + 8, Auth_Res, 2 + SIGNATURE_LEN);
        break;
    }
    default:
        break;
    }
}




